package com.fdb.efp.nls.service.impl.yed.queue;

import com.fdb.efp.nls.service.facade.NlsApplyInfoService;
import com.fdb.efp.nls.service.vo.NlsApplyInfoVO;
import com.fdb.basic.framework.core.constant.BaseConstant;
import com.fdb.basic.framework.core.constant.EsbRetCodeStandard;
import com.fdb.basic.framework.core.exception.BizException;
import com.fdb.basic.framework.core.threadpool.AbstractThreadTask;
import com.fdb.basic.framework.core.threadpool.ExecuteRtnInfo;
import com.fdb.basic.framework.core.util.DateTool;
import com.fdb.efp.nls.service.facade.PubSysInfoService;
import com.fdb.efp.cus.service.facade.CusIndivService;
import com.fdb.efp.cus.service.vo.CusIndivVO;
import com.fdb.efp.nls.service.vo.YedSignResultVO;
import com.fdb.efp.nls.service.vo.YedUploadRecordVO;
import com.fdb.efp.nls.service.facade.yed.YedSettleCertService;
import com.fdb.efp.nls.service.facade.yed.YedUploadService;
import com.fdb.efp.nls.service.vo.AccLoanVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.fdb.efp.basic.framework.mq.constant.TopicEnums.YED_SETTLE_CERT_QUEUE_TASK_TOPIC;

/**
 * 优e贷结清证明申请队列服务
 *
 * @author liangcongming :2020/8/12 8:36
 * @version 0.1
 * @date 2020/8/12 8:36
 * @since 2020/8/12 8:36
 */
@Service("yedSettleCertQueueHandleService")
@Scope(scopeName = "prototype")
public class YedSettleCertQueueHandle extends AbstractThreadTask {

    private static Logger logger = LoggerFactory.getLogger(YedSettleCertQueueHandle.class);

    // 结清证明文件后缀
    private static final String SUFFIX_FILE_NAME = "_settle_cert.pdf";

    private static final String prefix = "rc:" + YED_SETTLE_CERT_QUEUE_TASK_TOPIC.getTopicId() + ":";

    private AccLoanVO accLoanVO;

    public void setAccLoanVO(AccLoanVO accLoanVO) {
        this.accLoanVO = accLoanVO;
    }

    @Autowired
    @Qualifier("redisTemplate")
    private StringRedisTemplate template;

    @Autowired
    @Qualifier("pubSysInfoService")
    private PubSysInfoService pubSysInfoService;

    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;

    @Autowired
    @Qualifier("yedSettleCertService")
    private YedSettleCertService yedSettleCertService;

    @Autowired
    @Qualifier("nlsApplyInfoService")
    private NlsApplyInfoService nlsApplyInfoService;// 网贷申请基本信息

    @Autowired
    @Qualifier("yedUploadService")
    private  YedUploadService yedUploadService;

    @Override
    public ExecuteRtnInfo call() throws Exception {
        this.doTask();
        return new ExecuteRtnInfo(null, null, null, null, true);
    }

    /**
     * 结清证明文件申请步骤：
     * 1、根据借据填充模板内容
     * 2、调cfca签章，下载到本地
     * 3、后续定时任务上传至影像，并落库影像文件路径、模型代码等字段
     *
     * @throws Exception
     */
    @Override
    public void doTask() throws Exception {

        try{
            //1.获取营业日（签章落款时间）
            String openday = pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001);
            logger.info("开始校验营业日...");
            if (StringUtils.isEmpty(openday)) {
                logger.error("结清证明签章流程获取到的openday为空，用信流水号为：[{}]", accLoanVO.getApplySeq());
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "尊敬的客户您好，由于系统异常本次结清证明申请失败，请您稍后再试");
            }
            logger.info("营业日校验通过");
            logger.info("开始校验客户信息...");

            //2.获取客户信息表
            CusIndivVO cusIndivVO = new CusIndivVO();
            cusIndivVO.setCusId(Objects.requireNonNull(accLoanVO.getCusId()));
            cusIndivVO = cusIndivService.queryByPk(cusIndivVO);
            if (Objects.isNull(cusIndivVO)) {
                logger.error("获取的客户信息为空，用信流水号为：[{}]", accLoanVO.getApplySeq());
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "获取的客户信息为空");
            }
            logger.info("客户信息校验通过");
            logger.info("开始检验用信信息...");
            //3.获取申请时间
            NlsApplyInfoVO inNlsApplyInfoVO = new NlsApplyInfoVO();
            inNlsApplyInfoVO.setApplySeq(accLoanVO.getApplySeq());
            NlsApplyInfoVO queryNlsApplyInfoVO = nlsApplyInfoService.queryByPk(inNlsApplyInfoVO);
            if (Objects.isNull(queryNlsApplyInfoVO)) {
                logger.error("获取的客户用信信息为空，用信流水号为：[{}]", accLoanVO.getApplySeq());
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "获取的客户用信信息为空");
            }
            logger.info("用信信息校验通过");
            //4.初始模板信息
            Map<String, String> paramMap = initParamMap(cusIndivVO, openday, queryNlsApplyInfoVO.getApplyDate());

            //5.签章
            YedSignResultVO yedSignResultVO = yedSettleCertService.signature(accLoanVO.getApplySeq(), cusIndivVO.getAxqUsrId(), paramMap);
            logger.info("签章返回结果："+yedSignResultVO.isRetFlag());
            if (!yedSignResultVO.isRetFlag()) {
                logger.error(yedSignResultVO.getMsg());
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), yedSignResultVO.getMsg()+",用信申请流水号 ：" + accLoanVO.getApplySeq());
            }

            //6.签章后下载
            yedSignResultVO = yedSettleCertService.downSignFile(accLoanVO.getApplySeq(), yedSignResultVO.getAxqContNo(), accLoanVO.getApplySeq() + SUFFIX_FILE_NAME);
            logger.info("签章后下载返回结果："+yedSignResultVO.isRetFlag());
            if (!yedSignResultVO.isRetFlag()) {
                logger.error(yedSignResultVO.getMsg());
                throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), yedSignResultVO.getMsg()+",用信申请流水号 ：" + accLoanVO.getApplySeq());
            }

            //7.插入优e贷文件上传记录表
            YedUploadRecordVO yedUploadRecordVO = new YedUploadRecordVO();
            yedUploadRecordVO.setApplSeq(accLoanVO.getApplySeq());
            yedUploadRecordVO.setCreateTime(new Date());
            yedUploadRecordVO.setDealType("2");//处理阶段（1-授信 2-用信 3-借据）
            yedUploadRecordVO.setFileType("Y04");//Y01-授权书 Y02-借款合同 Y03-征信报告 Y04-结清证明
            yedUploadRecordVO.setFileUrl(yedSignResultVO.getFileFullPath());
            yedUploadRecordVO.setPrdId(queryNlsApplyInfoVO.getPrdId());
            yedUploadRecordVO.setUpErrMsg("");
            yedUploadRecordVO.setRecordId(UUID.randomUUID().toString().replace("-", ""));
            yedUploadRecordVO.setUpNum(0);
            yedUploadRecordVO.setUpSta(0);
            yedUploadRecordVO.setUpTime(new Date());
            int n = yedUploadService.insert(yedUploadRecordVO);
            logger.info("已插入优e贷文件上传记录表：" + n + "条记录！");

            logger.info("结清证明申请签章下载已完成，待定时任务上传影像平台,本地文件路径：" + yedSignResultVO.getFileFullPath());

        } catch (BizException bz){
            logger.error(bz.getMessage(),bz);
            // 删掉redis,防止失败后不能重新申请
            template.delete(prefix + accLoanVO.getApplySeq());
        } catch (Exception e){
            logger.error(e.getMessage(),e);
            // 删掉redis,防止失败后不能重新申请
            template.delete(prefix + accLoanVO.getApplySeq());
        }

    }


    /**
     * 获取合同填写参数MAP
     */
    private Map<String, String> initParamMap(CusIndivVO cusIndivVO, String openday, String applyDate) throws BizException{
        logger.info("【优e贷结清证明签订服务】组装合同模板填写参数开始 用信申请流水号 ：" + accLoanVO.getApplySeq());
        Map<String, String> map = new HashMap<String, String>();
        try {
            map.put("name", cusIndivVO.getCusName());
            map.put("certCode", cusIndivVO.getCertCode());
            map.put("applyYear", String.valueOf(DateTool.getYear(DateTool.parseDate(applyDate, DateTool.PATTERN_DEFAULT))));
            map.put("applyMonth", String.valueOf(DateTool.getMonth(DateTool.parseDate(applyDate, DateTool.PATTERN_DEFAULT))));
            map.put("applyDay", String.valueOf(DateTool.getDay(DateTool.parseDate(applyDate, DateTool.PATTERN_DEFAULT))));
            map.put("settlYear", String.valueOf(DateTool.getYear(DateTool.parseDate(accLoanVO.getSettlDate(), DateTool.PATTERN_DEFAULT))));
            map.put("settlMonth", String.valueOf(DateTool.getMonth(DateTool.parseDate(accLoanVO.getSettlDate(), DateTool.PATTERN_DEFAULT))));
            map.put("settlDay", String.valueOf(DateTool.getDay(DateTool.parseDate(accLoanVO.getSettlDate(), DateTool.PATTERN_DEFAULT))));
            map.put("prdName", accLoanVO.getPrdName());
            map.put("loanTerm", String.valueOf(accLoanVO.getLoanTerm()));
            map.put("settlDate", accLoanVO.getSettlDate());
            map.put("actualIntCumu", String.valueOf(accLoanVO.getActualIntCumu()));
            map.put("repaymentAccount", accLoanVO.getRepaymentAccount());
            map.put("loanAmount1",String.valueOf(accLoanVO.getLoanAmount())); //贷款金额
            map.put("loanAmount2",String.valueOf(accLoanVO.getLoanAmount())); //贷款本金
            map.put("loanStartDate",accLoanVO.getLoanStartDate()); //起息日期
            map.put("tranYear", String.valueOf(DateTool.getYear(DateTool.parseDate(openday, DateTool.PATTERN_DEFAULT))));
            map.put("tranMonth", String.valueOf(DateTool.getMonth(DateTool.parseDate(openday, DateTool.PATTERN_DEFAULT))));
            map.put("tranDay", String.valueOf(DateTool.getDay(DateTool.parseDate(openday, DateTool.PATTERN_DEFAULT))));
        } catch (Exception e) {
            logger.error("合同模板填写参数组装失败，用信申请流水号 ：" + accLoanVO.getApplySeq(),e);
            throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "合同模板填写参数组装失败，用信申请流水号 ：" + accLoanVO.getApplySeq());
        }
        logger.info("【优e贷结清证明签订服务】组装合同模板参数初始完成！");
        return map;
    }

}
